package com.weilele.mvvm.base.livedata

import android.widget.Toast
import androidx.lifecycle.MutableLiveData
import com.weilele.mvvm.utils.activity.toast
import com.weilele.mvvm.utils.printStackTrace

/**
 * 在挂起函数运行一段代码，并将错误和结果绑定在liveData，
 * 运行状态实时与liveData绑定
 * Obj:代码运行的对象作用域
 */
interface LiveDataRunnable {
    suspend operator fun <Bean> invoke(
        data: MutableLiveData<StatusData<Bean>>?,
        isToastError: Boolean = true/*是否toast出错误*/,
        errorCall: ((Throwable) -> Bean?)? = null,
        run: suspend () -> Bean?
    )
}

/**
 * [LiveDataRunnable]默认的请求处理
 */
object DefaultLiveDataRunnable : LiveDataRunnable {
    override suspend fun <Bean> invoke(
        data: MutableLiveData<StatusData<Bean>>?,
        isToastError: Boolean,
        errorCall: ((Throwable) -> Bean?)?,
        run: suspend () -> Bean?
    ) {
        try {
            data?.running()
            val result = run.invoke()
            if (result == null) {
                val errorMsg = "call result is null"
                val errorResult = errorCall?.invoke(NullResultException(errorMsg))
                if (errorResult == null) {
                    //这里不弹出提示
                    data?.error(errorMsg)
                } else {
                    data?.success(errorResult)
                }
            } else {
                data?.success(result)
            }
        } catch (e: Throwable) {
            printStackTrace { e }
            val errorResult = errorCall?.invoke(e)
            if (errorResult == null) {
                val errorMsg = e.message ?: "$e"
                if (isToastError) {
                    errorMsg.toast(Toast.LENGTH_LONG)
                }
                data?.error(errorMsg)
            } else {
                data?.success(errorResult)
            }
        }
    }
}

open class NullResultException(msg: String?) : Throwable(msg)